package org.vordel.incubator.examples.management_api;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import javax.wsdl.WSDLException;



import com.vordel.client.manager.actions.services.WSDLRetrievalTimeoutException;
import com.vordel.client.manager.actions.services.WebServiceDeleteatron;
import com.vordel.client.policy.gui.GenerationException;
import com.vordel.es.ESPK;
import com.vordel.es.Entity;
import com.vordel.es.EntityStore;
import com.vordel.es.EntityStoreException;
import com.vordel.es.EntityType;
import com.vordel.es.Field;
import com.vordel.trace.Trace;
import com.vordel.wsdl.Service;

public class WebServiceGroupManager extends EntityWrapperManager {

	private Session session;
	private static final String DEFAULT_NAME = "Web Services";
	
	WebServiceGroupManager(Session session) {
		super(session);
	}
	
	@Override
	protected String getContainerEntityTypeName() {
		// TODO Auto-generated method stub
		return "WebServiceRepository";
	}

	@Override
	protected String getContainerEntityName() {
		// TODO Auto-generated method stub
		return "Web Service Repository";
	}

	public WebServiceGroup getDefaultWebServiceGroup() throws Exception {
		
		Entity defaultEntity = this.getEntityByName(DEFAULT_NAME);
		return new WebServiceGroup(defaultEntity,this);
		
	}
	
	public WebServiceGroup getWebServiceGroup(String name) throws Exception {
		
		Entity wsgEntity = this.getEntityByName(name);
		if (wsgEntity == null) {
			return null;
		} else {
			return new WebServiceGroup(wsgEntity, this);
		}
	}
	
	public WebServiceGroup createWebServiceGroup(String name) throws Exception {
		
		Entity newEntity = this.createEntity(name);
		return new WebServiceGroup(newEntity,this);
	}

	
	
	@Override
	protected String getEntityTypeName() {
		// TODO Auto-generated method stub
		return "WebServiceGroup";
	}
	
	WebService createWebService(String name, String primaryWSDLURI, byte [] wsdl, String type, Entity parentEntity)throws Exception {
		
		EntityStore es = this.getSession().getEntityStore();
		EntityType webServiceEntityType = es.getTypeForName(type);
		Entity newWebService = new Entity(webServiceEntityType);
		
		newWebService.setStringField("name",name);
		newWebService.setLongField("createdOn", System.currentTimeMillis());
		
		ESPK newWebServiceESPK = es.addEntity(parentEntity.getPK(), newWebService);
		
		//This should refresh the entity to have the ESPK
		newWebService = es.getEntity(newWebServiceESPK);
		
		EntityType wsdlEntityType = es.getTypeForName("WSDL");
		Entity newWSDL = new Entity(wsdlEntityType);
		
		newWSDL.setStringField("uri", primaryWSDLURI);
		newWSDL.setBinaryValue("wsdl", wsdl);
		
		ESPK newWSDLESPK = es.addEntity(newWebServiceESPK, newWSDL);
		newWebService.setReferenceField("primaryWSDL", newWSDLESPK);
		
		es.updateEntity(newWebService);
		
		return new WebService(newWebService,this);
		
		
	}
	
	WebService createWebServiceFromWSDL(String wsdlUrl, WebServiceGroup wsg, HTTPService service) throws Exception {
	
		String url = this.importWSDLs(wsdlUrl, wsg, service);
		
		Collection<WebService> services = wsg.listWebServices();
		
		for (WebService ws: services) {
			
			if (ws.getPrimaryWSDL()==null) {
			
				Trace.info("NULL");
				continue;
			}
			
			if (ws.getPrimaryWSDL().getURI().equals(url)) {
				
				Trace.info("Found my Web Service...");
				return ws;
				
			} else {
				
				Trace.info(ws.getPrimaryWSDL().getURI()+"!="+url);
				
			}
			
		}
		
		return null;
		
	}
	
	
	
	public Schema createSchema(String url, String location, byte [] schema, Entity parentEntity) throws Exception {
		
		EntityStore es = this.getSession().getEntityStore();
		EntityType schemaEntityType = es.getTypeForName("Schema");
		Entity newSchema = new Entity(schemaEntityType);
		
		newSchema.setStringField("URL", url);
		newSchema.setStringField("location", location);
		newSchema.setStringField("contents", new String(schema));
		
		ESPK newSchemaESPK = es.addEntity(parentEntity.getPK(), newSchema);
		
		newSchema = es.getEntity(newSchemaESPK);
		
		return new Schema(newSchema,this);
	}
	
	 protected String importWSDLs(String wsdlUrl, WebServiceGroup wsg, HTTPService service) throws Exception {
	        
		 	EntityStore es = this.getSession().getEntityStore();
		 	Trace.setLevel(Trace.TRACE_INFO);
		 	
		 	

		 	java.util.Properties props = new java.util.Properties();
		 	props.put("WSDL_URL_1",wsdlUrl);
		 	
	        try {
	            List<ESPK> deploymentPks = new ArrayList<ESPK>();
	            deploymentPks.add(service.getEntity().getPK());  
	            
	            Trace.info(deploymentPks.toString());
	            
	            com.vordel.client.manager.actions.services.AddWebServiceServletProcessor processor = new com.vordel.client.manager.actions.services.AddWebServiceServletProcessor(es) {
	                protected void handleDuplicate(EntityStore es, Entity e, Service svc) throws GenerationException {
	                    Trace.info("Deleting pre-existing service");
	                    try {
	                        new WebServiceDeleteatron(es, e).deleteWS();
	                    } catch (EntityStoreException ese) {
	                        throw new GenerationException("Couldn't delete WS", ese);
	                    }
	                }
	            };
	            Set<String> sorted = new TreeSet<String>();
	            sorted.addAll(props.stringPropertyNames());
	            
	            String url = null;
	            
	            for (String key : sorted) {
	                if (key.startsWith("WSDL_URL_")) {
	                    url = props.getProperty(key);
	                    // Assume a relative path if not a http url
	                    if (!url.startsWith("http")) {
	                        File f = new File(url);
	                        url = f.toURI().toURL().toString();
	                    }
	                    Trace.info("Importing Web Service definition from: " + url);
	                    
	                    Entity parent = wsg.getEntity();
	                    
	                    Trace.info("Parent: "+parent);
	                    processor.addWebService(parent, url, deploymentPks, 60); 
	                    Trace.info("OK"); 
	                }
	            }            
	            
	            return url;
	        } catch (EntityStoreException e) {
	            e.printStackTrace();
	        } catch (WSDLException e) {
	            e.printStackTrace();
	        } catch (GenerationException e) {
	            e.printStackTrace();
	        } catch (WSDLRetrievalTimeoutException e) {
	            e.printStackTrace();
	        } catch (Exception e) {
	            e.printStackTrace();
	        }        
	        
	        return null;
	    }
	   
}
	

